package searchurl;

import java.awt.AWTException;
import java.awt.MenuItem;
import java.awt.PopupMenu;
import java.awt.SystemTray;
import java.awt.TrayIcon;
import java.io.IOException;
import java.util.logging.Level;
import java.util.logging.Logger;
import org.jdesktop.application.Action;
import org.jdesktop.application.ResourceMap;
import org.jdesktop.application.SingleFrameApplication;
import org.jdesktop.application.FrameView;
import org.jdesktop.application.Task;
import org.jdesktop.application.TaskMonitor;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.io.BufferedReader;
import java.io.File;
import java.io.FileInputStream;
import java.io.InputStreamReader;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
import javax.swing.DefaultListModel;
import javax.swing.Timer;
import javax.swing.Icon;
import javax.swing.ImageIcon;
import javax.swing.JButton;
import javax.swing.JDialog;
import javax.swing.JFileChooser;
import javax.swing.JFrame;
import javax.swing.JList;
import javax.swing.JOptionPane;
import javax.swing.filechooser.FileNameExtensionFilter;
import searchurl.common.DateTools;
import searchurl.common.SearchUrlContants;
import searchurl.common.TextFileTools;
import searchurl.dto.QueryConditionDto;
import searchurl.model.SearchResult;

/**
 * The application's main frame.
 * @author iridiumcao
 */
public class SearchUrlView extends FrameView {

    public SearchUrlView(SingleFrameApplication app) {
        super(app);

        initComponents();
        getFrame().setIconImage(new ImageIcon(getClass().getResource("resources/bb.jpeg")).getImage());
        getFrame().pack();
        //getFrame().setResizable(false);
        // status bar initialization - message timeout, idle icon and busy animation, etc
        ResourceMap resourceMap = getResourceMap();
        int messageTimeout = resourceMap.getInteger("StatusBar.messageTimeout");
        messageTimer = new Timer(messageTimeout, new ActionListener() {

            @Override
            public void actionPerformed(ActionEvent e) {
                statusMessageLabel.setText("");
            }
        });
        messageTimer.setRepeats(false);
        int busyAnimationRate = resourceMap.getInteger("StatusBar.busyAnimationRate");
        for (int i = 0; i < busyIcons.length; i++) {
            busyIcons[i] = resourceMap.getIcon("StatusBar.busyIcons[" + i + "]");
        }
        busyIconTimer = new Timer(busyAnimationRate, new ActionListener() {

            @Override
            public void actionPerformed(ActionEvent e) {
                busyIconIndex = (busyIconIndex + 1) % busyIcons.length;
                statusAnimationLabel.setIcon(busyIcons[busyIconIndex]);
            }
        });
        idleIcon = resourceMap.getIcon("StatusBar.idleIcon");
        statusAnimationLabel.setIcon(idleIcon);
        progressBar.setVisible(false);

        // connecting action tasks to status bar via TaskMonitor
        TaskMonitor taskMonitor = new TaskMonitor(getApplication().getContext());
        taskMonitor.addPropertyChangeListener(new java.beans.PropertyChangeListener() {

            @Override
            public void propertyChange(java.beans.PropertyChangeEvent evt) {
                String propertyName = evt.getPropertyName();
                if ("started".equals(propertyName)) {
                    if (!busyIconTimer.isRunning()) {
                        statusAnimationLabel.setIcon(busyIcons[0]);
                        busyIconIndex = 0;
                        busyIconTimer.start();
                    }
                    progressBar.setVisible(true);
                    progressBar.setIndeterminate(true);
                } else if ("done".equals(propertyName)) {
                    busyIconTimer.stop();
                    statusAnimationLabel.setIcon(idleIcon);
                    progressBar.setVisible(false);
                    progressBar.setValue(0);
                } else if ("message".equals(propertyName)) {
                    String text = (String) (evt.getNewValue());
                    statusMessageLabel.setText((text == null) ? "" : text);
                    messageTimer.restart();
                } else if ("progress".equals(propertyName)) {
                    int value = (Integer) (evt.getNewValue());
                    progressBar.setVisible(true);
                    progressBar.setIndeterminate(false);
                    progressBar.setValue(value);
                }
            }
        });

        if (SystemTray.isSupported()) {//判断系统是否托盘
            //创建一个托盘图标对象
            TrayIcon icon = new TrayIcon(new ImageIcon(getClass().getResource("resources/task_icon.png")).getImage(), "SearchURL");
            //创建弹出菜单
            PopupMenu menu = new PopupMenu();
            //添加一个用于退出的按钮
            MenuItem item = new MenuItem(resourceMap.getString("tray.exit"));
            item.addActionListener(new ActionListener() {

                public void actionPerformed(ActionEvent e) {
                    System.exit(0);
                }
            });
            menu.add(item);
            //添加弹出菜单到托盘图标
            icon.setPopupMenu(menu);
            SystemTray tray = SystemTray.getSystemTray();//获取系统托盘
            try {
                tray.add(icon);//将托盘图表添加到系统托盘
            } catch (AWTException ex) {
                Logger.getLogger(SearchUrlView.class.getName()).log(Level.SEVERE, null, ex);
            }
        }
    }

    @Action
    public void showAboutBox() {
        if (aboutBox == null) {
            JFrame mainFrame = SearchUrlApp.getApplication().getMainFrame();
            aboutBox = new SearchUrlAboutBox(mainFrame);
            aboutBox.setLocationRelativeTo(mainFrame);
        }
        SearchUrlApp.getApplication().show(aboutBox);
    }

    /** This method is called from within the constructor to
     * initialize the form.
     * WARNING: Do NOT modify this code. The content of this method is
     * always regenerated by the Form Editor.
     */
    @SuppressWarnings("unchecked")
    // <editor-fold defaultstate="collapsed" desc="Generated Code">//GEN-BEGIN:initComponents
    private void initComponents() {

        mainPanel = new javax.swing.JPanel();
        appTitleLabel = new javax.swing.JLabel();
        resetButton = new javax.swing.JButton();
        queryButton = new javax.swing.JButton();
        destDirPanel = new javax.swing.JPanel();
        jScrollPane2 = new javax.swing.JScrollPane();
        dirsList = new javax.swing.JList();
        removeDirButton = new javax.swing.JButton();
        saveDirsButton = new javax.swing.JButton();
        loadDirsButton = new javax.swing.JButton();
        addDirButton = new javax.swing.JButton();
        preFilterPanel = new javax.swing.JPanel();
        preFilterTextField = new javax.swing.JTextField();
        preFilterButton = new javax.swing.JButton();
        preFilterCheckBox = new javax.swing.JCheckBox();
        restrict211CheckBox = new javax.swing.JCheckBox();
        keywordsFilesPanel = new javax.swing.JPanel();
        jScrollPane1 = new javax.swing.JScrollPane();
        keywordFilesList = new javax.swing.JList();
        addButton = new javax.swing.JButton();
        removeButton = new javax.swing.JButton();
        saveListButton = new javax.swing.JButton();
        loadListButton = new javax.swing.JButton();
        stopButton = new javax.swing.JButton();
        menuBar = new javax.swing.JMenuBar();
        javax.swing.JMenu fileMenu = new javax.swing.JMenu();
        javax.swing.JMenuItem exitMenuItem = new javax.swing.JMenuItem();
        javax.swing.JMenu helpMenu = new javax.swing.JMenu();
        javax.swing.JMenuItem aboutMenuItem = new javax.swing.JMenuItem();
        statusPanel = new javax.swing.JPanel();
        javax.swing.JSeparator statusPanelSeparator = new javax.swing.JSeparator();
        statusMessageLabel = new javax.swing.JLabel();
        statusAnimationLabel = new javax.swing.JLabel();
        progressBar = new javax.swing.JProgressBar();
        searchDirFileChooser = new javax.swing.JFileChooser();
        keywordFileFileChooser = new javax.swing.JFileChooser();
        saveResultFileChooser = new javax.swing.JFileChooser();
        saveListFileChooser = new javax.swing.JFileChooser();
        loadListFileChooser = new javax.swing.JFileChooser();
        prefilterFileChooser = new javax.swing.JFileChooser();

        mainPanel.setName("mainPanel"); // NOI18N

        appTitleLabel.setFont(new java.awt.Font("Arial", 0, 18));
        org.jdesktop.application.ResourceMap resourceMap = org.jdesktop.application.Application.getInstance(searchurl.SearchUrlApp.class).getContext().getResourceMap(SearchUrlView.class);
        appTitleLabel.setForeground(resourceMap.getColor("appTitleLabel.foreground")); // NOI18N
        appTitleLabel.setText(resourceMap.getString("appTitleLabel.text")); // NOI18N
        appTitleLabel.setName("appTitleLabel"); // NOI18N

        resetButton.setText(resourceMap.getString("resetButton.text")); // NOI18N
        resetButton.setName("resetButton"); // NOI18N
        resetButton.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                resetButtonActionPerformed(evt);
            }
        });

        javax.swing.ActionMap actionMap = org.jdesktop.application.Application.getInstance(searchurl.SearchUrlApp.class).getContext().getActionMap(SearchUrlView.class, this);
        queryButton.setAction(actionMap.get("startQuery")); // NOI18N
        queryButton.setText(resourceMap.getString("queryButton.text")); // NOI18N
        queryButton.setName("queryButton"); // NOI18N
        queryButton.addMouseListener(new java.awt.event.MouseAdapter() {
            public void mouseReleased(java.awt.event.MouseEvent evt) {
                queryButtonMouseReleased(evt);
            }
        });

        destDirPanel.setBorder(javax.swing.BorderFactory.createTitledBorder(resourceMap.getString("destDirPanel.border.title"))); // NOI18N
        destDirPanel.setName("destDirPanel"); // NOI18N

        jScrollPane2.setName("jScrollPane2"); // NOI18N
        jScrollPane2.setPreferredSize(new java.awt.Dimension(258, 130));

        dirsList.setName("dirsList"); // NOI18N
        jScrollPane2.setViewportView(dirsList);

        removeDirButton.setText(resourceMap.getString("removeDirButton.text")); // NOI18N
        removeDirButton.setToolTipText(resourceMap.getString("removeDirButton.toolTipText")); // NOI18N
        removeDirButton.setName("removeDirButton"); // NOI18N
        removeDirButton.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                removeButtonActionPerformed(evt);
            }
        });

        saveDirsButton.setText(resourceMap.getString("saveDirsButton.text")); // NOI18N
        saveDirsButton.setToolTipText(resourceMap.getString("saveDirsButton.toolTipText")); // NOI18N
        saveDirsButton.setName("saveDirsButton"); // NOI18N
        saveDirsButton.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                saveListButtonActionPerformed(evt);
            }
        });

        loadDirsButton.setText(resourceMap.getString("loadDirsButton.text")); // NOI18N
        loadDirsButton.setToolTipText(resourceMap.getString("loadDirsButton.toolTipText")); // NOI18N
        loadDirsButton.setName("loadDirsButton"); // NOI18N
        loadDirsButton.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                loadListButtonActionPerformed(evt);
            }
        });

        addDirButton.setText(resourceMap.getString("addDirButton.text")); // NOI18N
        addDirButton.setToolTipText(resourceMap.getString("addDirButton.toolTipText")); // NOI18N
        addDirButton.setName("addDirButton"); // NOI18N
        addDirButton.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                addDirButtonActionPerformed(evt);
            }
        });

        javax.swing.GroupLayout destDirPanelLayout = new javax.swing.GroupLayout(destDirPanel);
        destDirPanel.setLayout(destDirPanelLayout);
        destDirPanelLayout.setHorizontalGroup(
            destDirPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(javax.swing.GroupLayout.Alignment.TRAILING, destDirPanelLayout.createSequentialGroup()
                .addContainerGap()
                .addComponent(jScrollPane2, javax.swing.GroupLayout.DEFAULT_SIZE, 467, Short.MAX_VALUE)
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                .addGroup(destDirPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                    .addGroup(destDirPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.TRAILING, false)
                        .addComponent(addDirButton, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
                        .addComponent(removeDirButton, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
                        .addComponent(saveDirsButton, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))
                    .addComponent(loadDirsButton))
                .addGap(14, 14, 14))
        );
        destDirPanelLayout.setVerticalGroup(
            destDirPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(javax.swing.GroupLayout.Alignment.TRAILING, destDirPanelLayout.createSequentialGroup()
                .addContainerGap()
                .addGroup(destDirPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                    .addGroup(destDirPanelLayout.createSequentialGroup()
                        .addComponent(addDirButton)
                        .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                        .addComponent(removeDirButton)
                        .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                        .addComponent(saveDirsButton)
                        .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                        .addComponent(loadDirsButton))
                    .addComponent(jScrollPane2, javax.swing.GroupLayout.Alignment.TRAILING, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE))
                .addContainerGap())
        );

        preFilterPanel.setBorder(javax.swing.BorderFactory.createTitledBorder(resourceMap.getString("preFilterPanel.border.title"))); // NOI18N
        preFilterPanel.setName("preFilterPanel"); // NOI18N

        preFilterTextField.setToolTipText(resourceMap.getString("preFilterTextField.toolTipText")); // NOI18N
        preFilterTextField.setName("preFilterTextField"); // NOI18N

        preFilterButton.setText(resourceMap.getString("preFilterButton.text")); // NOI18N
        preFilterButton.setToolTipText(resourceMap.getString("preFilterButton.toolTipText")); // NOI18N
        preFilterButton.setName("preFilterButton"); // NOI18N
        preFilterButton.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                preFilterButtonActionPerformed(evt);
            }
        });

        preFilterCheckBox.setSelected(true);
        preFilterCheckBox.setText(resourceMap.getString("preFilterCheckBox.text")); // NOI18N
        preFilterCheckBox.setToolTipText(resourceMap.getString("preFilterCheckBox.toolTipText")); // NOI18N
        preFilterCheckBox.setName("preFilterCheckBox"); // NOI18N
        preFilterCheckBox.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                preFilterCheckBoxActionPerformed(evt);
            }
        });

        restrict211CheckBox.setText(resourceMap.getString("restrict211CheckBox.text")); // NOI18N
        restrict211CheckBox.setToolTipText(resourceMap.getString("restrict211CheckBox.toolTipText")); // NOI18N
        restrict211CheckBox.setName("restrict211CheckBox"); // NOI18N

        javax.swing.GroupLayout preFilterPanelLayout = new javax.swing.GroupLayout(preFilterPanel);
        preFilterPanel.setLayout(preFilterPanelLayout);
        preFilterPanelLayout.setHorizontalGroup(
            preFilterPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(preFilterPanelLayout.createSequentialGroup()
                .addContainerGap()
                .addGroup(preFilterPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                    .addGroup(preFilterPanelLayout.createSequentialGroup()
                        .addComponent(preFilterCheckBox)
                        .addGap(18, 18, 18)
                        .addComponent(restrict211CheckBox))
                    .addGroup(javax.swing.GroupLayout.Alignment.TRAILING, preFilterPanelLayout.createSequentialGroup()
                        .addComponent(preFilterTextField, javax.swing.GroupLayout.DEFAULT_SIZE, 479, Short.MAX_VALUE)
                        .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED)
                        .addComponent(preFilterButton, javax.swing.GroupLayout.PREFERRED_SIZE, 93, javax.swing.GroupLayout.PREFERRED_SIZE)))
                .addContainerGap())
        );
        preFilterPanelLayout.setVerticalGroup(
            preFilterPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(preFilterPanelLayout.createSequentialGroup()
                .addContainerGap()
                .addGroup(preFilterPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
                    .addComponent(preFilterCheckBox)
                    .addComponent(restrict211CheckBox))
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                .addGroup(preFilterPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
                    .addComponent(preFilterTextField, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
                    .addComponent(preFilterButton))
                .addContainerGap())
        );

        keywordsFilesPanel.setBorder(javax.swing.BorderFactory.createTitledBorder(resourceMap.getString("keywordsFilesPanel.border.title"))); // NOI18N
        keywordsFilesPanel.setName("keywordsFilesPanel"); // NOI18N

        jScrollPane1.setName("jScrollPane1"); // NOI18N

        keywordFilesList.setName("keywordFilesList"); // NOI18N
        jScrollPane1.setViewportView(keywordFilesList);

        addButton.setText(resourceMap.getString("addButton.text")); // NOI18N
        addButton.setToolTipText(resourceMap.getString("addButton.toolTipText")); // NOI18N
        addButton.setName("addButton"); // NOI18N
        addButton.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                addButtonActionPerformed(evt);
            }
        });

        removeButton.setText(resourceMap.getString("removeButton.text")); // NOI18N
        removeButton.setToolTipText(resourceMap.getString("removeButton.toolTipText")); // NOI18N
        removeButton.setName("removeButton"); // NOI18N
        removeButton.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                removeButtonActionPerformed(evt);
            }
        });

        saveListButton.setText(resourceMap.getString("saveListButton.text")); // NOI18N
        saveListButton.setToolTipText(resourceMap.getString("saveListButton.toolTipText")); // NOI18N
        saveListButton.setName("saveListButton"); // NOI18N
        saveListButton.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                saveListButtonActionPerformed(evt);
            }
        });

        loadListButton.setText(resourceMap.getString("loadListButton.text")); // NOI18N
        loadListButton.setToolTipText(resourceMap.getString("loadListButton.toolTipText")); // NOI18N
        loadListButton.setName("loadListButton"); // NOI18N
        loadListButton.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                loadListButtonActionPerformed(evt);
            }
        });

        javax.swing.GroupLayout keywordsFilesPanelLayout = new javax.swing.GroupLayout(keywordsFilesPanel);
        keywordsFilesPanel.setLayout(keywordsFilesPanelLayout);
        keywordsFilesPanelLayout.setHorizontalGroup(
            keywordsFilesPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(javax.swing.GroupLayout.Alignment.TRAILING, keywordsFilesPanelLayout.createSequentialGroup()
                .addContainerGap()
                .addComponent(jScrollPane1, javax.swing.GroupLayout.DEFAULT_SIZE, 471, Short.MAX_VALUE)
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                .addGroup(keywordsFilesPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.TRAILING, false)
                    .addComponent(addButton, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
                    .addComponent(loadListButton, javax.swing.GroupLayout.Alignment.LEADING, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
                    .addComponent(removeButton, javax.swing.GroupLayout.Alignment.LEADING, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
                    .addComponent(saveListButton, javax.swing.GroupLayout.Alignment.LEADING, 0, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))
                .addContainerGap())
        );
        keywordsFilesPanelLayout.setVerticalGroup(
            keywordsFilesPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(javax.swing.GroupLayout.Alignment.TRAILING, keywordsFilesPanelLayout.createSequentialGroup()
                .addContainerGap()
                .addGroup(keywordsFilesPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                    .addComponent(jScrollPane1, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
                    .addGroup(keywordsFilesPanelLayout.createSequentialGroup()
                        .addComponent(addButton)
                        .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                        .addComponent(removeButton)
                        .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                        .addComponent(saveListButton)
                        .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                        .addComponent(loadListButton)))
                .addContainerGap())
        );

        stopButton.setAction(actionMap.get("stopQuery")); // NOI18N
        stopButton.setText(resourceMap.getString("stopButton.text")); // NOI18N
        stopButton.setName("stopButton"); // NOI18N

        javax.swing.GroupLayout mainPanelLayout = new javax.swing.GroupLayout(mainPanel);
        mainPanel.setLayout(mainPanelLayout);
        mainPanelLayout.setHorizontalGroup(
            mainPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(javax.swing.GroupLayout.Alignment.TRAILING, mainPanelLayout.createSequentialGroup()
                .addGroup(mainPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.TRAILING)
                    .addGroup(javax.swing.GroupLayout.Alignment.LEADING, mainPanelLayout.createSequentialGroup()
                        .addContainerGap()
                        .addComponent(preFilterPanel, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))
                    .addGroup(javax.swing.GroupLayout.Alignment.LEADING, mainPanelLayout.createSequentialGroup()
                        .addContainerGap()
                        .addComponent(destDirPanel, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))
                    .addGroup(javax.swing.GroupLayout.Alignment.LEADING, mainPanelLayout.createSequentialGroup()
                        .addGap(210, 210, 210)
                        .addComponent(appTitleLabel, javax.swing.GroupLayout.PREFERRED_SIZE, 206, javax.swing.GroupLayout.PREFERRED_SIZE))
                    .addGroup(mainPanelLayout.createSequentialGroup()
                        .addContainerGap()
                        .addComponent(resetButton)
                        .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                        .addComponent(queryButton, javax.swing.GroupLayout.PREFERRED_SIZE, 63, javax.swing.GroupLayout.PREFERRED_SIZE)
                        .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                        .addComponent(stopButton, javax.swing.GroupLayout.PREFERRED_SIZE, 66, javax.swing.GroupLayout.PREFERRED_SIZE)
                        .addGap(35, 35, 35))
                    .addGroup(javax.swing.GroupLayout.Alignment.LEADING, mainPanelLayout.createSequentialGroup()
                        .addContainerGap()
                        .addComponent(keywordsFilesPanel, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)))
                .addContainerGap())
        );
        mainPanelLayout.setVerticalGroup(
            mainPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(mainPanelLayout.createSequentialGroup()
                .addContainerGap()
                .addComponent(appTitleLabel, javax.swing.GroupLayout.PREFERRED_SIZE, 30, javax.swing.GroupLayout.PREFERRED_SIZE)
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED)
                .addComponent(destDirPanel, javax.swing.GroupLayout.DEFAULT_SIZE, 184, Short.MAX_VALUE)
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED)
                .addComponent(preFilterPanel, javax.swing.GroupLayout.PREFERRED_SIZE, 84, javax.swing.GroupLayout.PREFERRED_SIZE)
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED)
                .addComponent(keywordsFilesPanel, javax.swing.GroupLayout.PREFERRED_SIZE, 171, javax.swing.GroupLayout.PREFERRED_SIZE)
                .addGap(18, 18, Short.MAX_VALUE)
                .addGroup(mainPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
                    .addComponent(queryButton)
                    .addComponent(resetButton)
                    .addComponent(stopButton))
                .addContainerGap())
        );

        destDirPanel.getAccessibleContext().setAccessibleName(resourceMap.getString("jPanel1.AccessibleContext.accessibleName")); // NOI18N
        preFilterPanel.getAccessibleContext().setAccessibleName(resourceMap.getString("preFilterPanel.AccessibleContext.accessibleName")); // NOI18N

        menuBar.setName("menuBar"); // NOI18N

        fileMenu.setText(resourceMap.getString("fileMenu.text")); // NOI18N
        fileMenu.setName("fileMenu"); // NOI18N

        exitMenuItem.setAction(actionMap.get("quit")); // NOI18N
        exitMenuItem.setName("exitMenuItem"); // NOI18N
        fileMenu.add(exitMenuItem);

        menuBar.add(fileMenu);

        helpMenu.setText(resourceMap.getString("helpMenu.text")); // NOI18N
        helpMenu.setName("helpMenu"); // NOI18N

        aboutMenuItem.setAction(actionMap.get("showAboutBox")); // NOI18N
        aboutMenuItem.setName("aboutMenuItem"); // NOI18N
        helpMenu.add(aboutMenuItem);

        menuBar.add(helpMenu);

        statusPanel.setName("statusPanel"); // NOI18N

        statusPanelSeparator.setName("statusPanelSeparator"); // NOI18N

        statusMessageLabel.setName("statusMessageLabel"); // NOI18N

        statusAnimationLabel.setHorizontalAlignment(javax.swing.SwingConstants.LEFT);
        statusAnimationLabel.setName("statusAnimationLabel"); // NOI18N

        progressBar.setName("progressBar"); // NOI18N

        javax.swing.GroupLayout statusPanelLayout = new javax.swing.GroupLayout(statusPanel);
        statusPanel.setLayout(statusPanelLayout);
        statusPanelLayout.setHorizontalGroup(
            statusPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addComponent(statusPanelSeparator, javax.swing.GroupLayout.DEFAULT_SIZE, 638, Short.MAX_VALUE)
            .addGroup(statusPanelLayout.createSequentialGroup()
                .addContainerGap()
                .addComponent(statusMessageLabel)
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED, 468, Short.MAX_VALUE)
                .addComponent(progressBar, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                .addComponent(statusAnimationLabel)
                .addContainerGap())
        );
        statusPanelLayout.setVerticalGroup(
            statusPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(statusPanelLayout.createSequentialGroup()
                .addComponent(statusPanelSeparator, javax.swing.GroupLayout.PREFERRED_SIZE, 2, javax.swing.GroupLayout.PREFERRED_SIZE)
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
                .addGroup(statusPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
                    .addComponent(statusMessageLabel)
                    .addComponent(statusAnimationLabel)
                    .addComponent(progressBar, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE))
                .addGap(3, 3, 3))
        );

        searchDirFileChooser.setDialogTitle(resourceMap.getString("searchDirFileChooser.dialogTitle")); // NOI18N
        searchDirFileChooser.setFileSelectionMode(javax.swing.JFileChooser.DIRECTORIES_ONLY);
        searchDirFileChooser.setMultiSelectionEnabled(true);
        searchDirFileChooser.setName("searchDirFileChooser"); // NOI18N

        keywordFileFileChooser.setDialogTitle(resourceMap.getString("keywordFileFileChooser.dialogTitle")); // NOI18N
        keywordFileFileChooser.setFileFilter(new FileNameExtensionFilter("Text or MS Excel file(*.txt, *.xls, *.xlsx)", "txt", "xls", "xlsx"));
        keywordFileFileChooser.setMultiSelectionEnabled(true);
        keywordFileFileChooser.setName("keywordFileFileChooser"); // NOI18N

        saveResultFileChooser.setDialogType(javax.swing.JFileChooser.SAVE_DIALOG);
        saveResultFileChooser.setName("saveResultFileChooser"); // NOI18N

        saveListFileChooser.setDialogType(javax.swing.JFileChooser.SAVE_DIALOG);
        saveListFileChooser.setName("saveListFileChooser"); // NOI18N

        loadListFileChooser.setFileFilter(new FileNameExtensionFilter("text file", "txt"));
        loadListFileChooser.setName("loadListFileChooser"); // NOI18N

        prefilterFileChooser.setFileFilter(new FileNameExtensionFilter("Text or MS Excel file(*.txt, *.xls, *.xlsx)", "txt", "xls", "xlsx"));
        prefilterFileChooser.setName("prefilterFileChooser"); // NOI18N

        setComponent(mainPanel);
        setMenuBar(menuBar);
        setStatusBar(statusPanel);
    }// </editor-fold>//GEN-END:initComponents

private void addButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_addButtonActionPerformed
    try {
        keywordFilesList.setModel(keywordFileListModel);
        int returnVal = keywordFileFileChooser.showOpenDialog(mainPanel);
        if (returnVal == JFileChooser.APPROVE_OPTION) {
            File[] files = keywordFileFileChooser.getSelectedFiles();
            for (File file : files) {
                String filePath = file.getCanonicalPath();
                boolean flag = checkTxt(filePath, evt);
                if (flag) {
                    keywordFileListModel.addElement(filePath);
                }
            }
        }
    } catch (IOException ex) {
        Logger.getLogger(SearchUrlView.class.getName()).log(Level.SEVERE, null, ex);
    }

}//GEN-LAST:event_addButtonActionPerformed

private void removeButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_removeButtonActionPerformed
    JList list = null;
    DefaultListModel model = null;
    if (evt.getSource() == removeDirButton) {
        list = dirsList;
        model = dirsListModel;
    } else if (evt.getSource() == removeButton) {
        list = keywordFilesList;
        model = keywordFileListModel;
    }
    int[] indices = list.getSelectedIndices();
    int i = 0;
    for (int index : indices) {
        model.remove(index - i);
        i++;
        list.setSelectedIndex(0);
    }
}//GEN-LAST:event_removeButtonActionPerformed

private void resetButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_resetButtonActionPerformed
    dirsListModel.removeAllElements();
    restrict211CheckBox.setSelected(false);
    preFilterCheckBox.setSelected(true);
    preFilterTextField.setText("");
    keywordFileListModel.removeAllElements();
}//GEN-LAST:event_resetButtonActionPerformed

    private void saveListButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_saveListButtonActionPerformed
        org.jdesktop.application.ResourceMap resourceMap = org.jdesktop.application.Application.getInstance(searchurl.SearchUrlApp.class).getContext().getResourceMap(SearchUrlView.class);
        JList list = null;
        String defaultFileName = null;

        if (evt.getSource() == saveDirsButton) {
            list = dirsList;
            defaultFileName = SearchUrlContants.SEARCH_DIRS_LIST_NAME;
        } else if (evt.getSource() == saveListButton) {
            list = keywordFilesList;
            defaultFileName = SearchUrlContants.KEYWORKD_FILES_LIST_NAME;
        }

        StringBuilder sb = new StringBuilder();
        for (int i = 0; i < list.getModel().getSize(); i++) {
            sb.append(list.getModel().getElementAt(i)).append(SearchUrlContants.LINE_SEPARATOR);
        }
        if (sb.length() == 0) {
            JOptionPane.showMessageDialog(mainPanel, resourceMap.getString("warning.saveblank.content"), resourceMap.getString("warning.title"), JOptionPane.WARNING_MESSAGE);
            return;
        }

        saveListFileChooser.setSelectedFile(new File(defaultFileName + ".txt"));
        int option = saveListFileChooser.showSaveDialog(mainPanel);
        if (option == JFileChooser.APPROVE_OPTION) {
            File file = saveListFileChooser.getSelectedFile();
            if (!file.getName().endsWith(".txt")) {
                file = new File(file.getParentFile(), file.getName() + ".txt");
            }
            if (file.exists()) {
                int status = JOptionPane.showConfirmDialog(mainPanel, "\"" + file.getName() + "\" " + resourceMap.getString("warning.overwrite.content"), resourceMap.getString("warning.title"), JOptionPane.WARNING_MESSAGE);
                if (status == JOptionPane.CANCEL_OPTION || status == JOptionPane.NO_OPTION || status == JOptionPane.CLOSED_OPTION) {
                    saveListButtonActionPerformed(evt);
                }
            }

            TextFileTools.writeTextToFile(sb.toString(), file);
        }
    }//GEN-LAST:event_saveListButtonActionPerformed

    private void loadListButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_loadListButtonActionPerformed
        JList list = null;
        DefaultListModel model = null;
        if (evt.getSource() == loadDirsButton) {
            list = dirsList;
            model = dirsListModel;
        } else if (evt.getSource() == loadListButton) {
            list = keywordFilesList;
            model = keywordFileListModel;
        }
        list.setModel(model);
        int returnVal = loadListFileChooser.showOpenDialog(mainPanel);
        if (returnVal == JFileChooser.APPROVE_OPTION) {
            File file = loadListFileChooser.getSelectedFile();
            FileInputStream fis = null;
            InputStreamReader isr = null;
            BufferedReader bfr = null;
            try {
                fis = new FileInputStream(file);
                isr = new InputStreamReader(fis, "UTF-8");
                bfr = new BufferedReader(isr);
                String line = bfr.readLine();
                while (line != null && !line.equals("")) {
                    line = line.trim();
                    if (!model.contains(line)) {
                        model.addElement(line);
                    }
                    line = bfr.readLine();
                }
            } catch (IOException e) {
                e.printStackTrace();
            } finally {
                try {
                    if (bfr != null) {
                        bfr.close();
                    }
                    if (isr != null) {
                        isr.close();
                    }
                    if (fis != null) {
                        fis.close();
                    }
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }

        }
    }//GEN-LAST:event_loadListButtonActionPerformed

    private void preFilterButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_preFilterButtonActionPerformed
        int returnVal = prefilterFileChooser.showOpenDialog(mainPanel);
        if (returnVal == JFileChooser.APPROVE_OPTION) {
            File file = prefilterFileChooser.getSelectedFile();
            preFilterTextField.setText(file.getAbsolutePath());
        }
    }//GEN-LAST:event_preFilterButtonActionPerformed

    private void preFilterCheckBoxActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_preFilterCheckBoxActionPerformed
        if (!preFilterCheckBox.isSelected()) {
            preFilterButton.setEnabled(false);
            preFilterTextField.setEnabled(false);
        } else {
            preFilterButton.setEnabled(true);
            preFilterTextField.setEnabled(true);
        }
    }//GEN-LAST:event_preFilterCheckBoxActionPerformed

    private void addDirButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_addDirButtonActionPerformed
        try {
            dirsList.setModel(dirsListModel);
            int returnVal = searchDirFileChooser.showOpenDialog(mainPanel);
            if (returnVal == JFileChooser.APPROVE_OPTION) {
                File[] files = searchDirFileChooser.getSelectedFiles();
                for (File file : files) {
                    String filePath = file.getCanonicalPath();
                    boolean flag = checkTxt(filePath, evt);
                    if (flag) {
                        dirsListModel.addElement(filePath);
                    }
                }
            }
        } catch (IOException ex) {
            Logger.getLogger(SearchUrlView.class.getName()).log(Level.SEVERE, null, ex);
        }
    }//GEN-LAST:event_addDirButtonActionPerformed

    private void queryButtonMouseReleased(java.awt.event.MouseEvent evt) {//GEN-FIRST:event_queryButtonMouseReleased
        if (isStop == false) {
            setHasPrepared(false);
            // isStop = false;
            setIsQuerying(!((JButton) (evt.getSource())).isEnabled());
        }
    }//GEN-LAST:event_queryButtonMouseReleased
    private boolean hasPrepared = true;

    public boolean isHasPrepared() {
        return hasPrepared;
    }

    public void setHasPrepared(boolean b) {
        boolean old = isHasPrepared();
        this.hasPrepared = b;
        firePropertyChange("hasPrepared", old, isHasPrepared());
    }
    private boolean isQuerying = false;

    public boolean isIsQuerying() {
        return isQuerying;
    }

    public void setIsQuerying(boolean b) {
        boolean old = isIsQuerying();
        this.isQuerying = b;
        firePropertyChange("isQuerying", old, isIsQuerying());
    }

    private boolean checkTxt(String filePath, java.awt.event.ActionEvent evt) {
        org.jdesktop.application.ResourceMap resourceMap = org.jdesktop.application.Application.getInstance(searchurl.SearchUrlApp.class).getContext().getResourceMap(SearchUrlView.class);
        String message = null;
//        if (!filePath.toLowerCase().matches(".+\\.txt")) {
//            message = "Only text file(*.txt) is available! Please choose another one.";
//        }
        DefaultListModel model = null;
        if (evt.getSource() == addDirButton) {
            model = dirsListModel;
        } else if (evt.getSource() == addButton) {
            model = keywordFileListModel;
        }

        if (model.contains(filePath)) {
            message = resourceMap.getString("warning.duplicatefileordir.content");
        }
        if (message != null) {
            JOptionPane.showMessageDialog(mainPanel, message, resourceMap.getString("warning.title"), JOptionPane.WARNING_MESSAGE);
            return false;
        }
        return true;
    }

    @Action(enabledProperty = "hasPrepared")
    public Task startQuery() {
        queryTask = new StartQueryTask(getApplication());
        return queryTask;
    }

    private class StartQueryTask extends org.jdesktop.application.Task<String, Void> {

        org.jdesktop.application.ResourceMap resourceMap = org.jdesktop.application.Application.getInstance(searchurl.SearchUrlApp.class).getContext().getResourceMap(SearchUrlView.class);
        private QueryConditionDto queryDto = null;
        // boolean flag = false;

        StartQueryTask(org.jdesktop.application.Application app) {
            // Runs on the EDT.  Copy GUI state that
            // doInBackground() depends on from parameters
            // to StartQueryTask fields, here.
            super(app);
            Set<String> searchDirPathes = new HashSet<String>();
            int dirsListSize = dirsListModel.getSize();
            String warningMessage = "";
            if (dirsListSize == 0) {
                warningMessage = resourceMap.getString("warning.blankdirs.content");
            }

            String preFilterPath = preFilterTextField.getText();
            if (preFilterCheckBox.isSelected() && preFilterPath.equals("")) {
                if (warningMessage.equals("")) {
                    warningMessage = resourceMap.getString("warning.prefilter.content");
                }
                preFilterButton.requestFocusInWindow();
            }

            Set<String> keywordFiles = new HashSet<String>();
            int keywordFileListSize = keywordFileListModel.getSize();
            if (keywordFileListSize == 0) {
                if (warningMessage.equals("")) {
                    warningMessage = resourceMap.getString("warning.keywordfileslist.content");
                }
            }
            if (!warningMessage.equals("")) {
                JOptionPane.showMessageDialog(mainPanel, warningMessage, resourceMap.getString("warning.title"), JOptionPane.WARNING_MESSAGE);
                isStop = true;
            }

            if (dirsListSize > 0 && keywordFileListSize > 0 && !(preFilterCheckBox.isSelected() && preFilterPath.equals(""))) {
                queryDto = new QueryConditionDto();
                queryDto.setRestrict211(restrict211CheckBox.isSelected());
                queryDto.setEnablePreFilter(preFilterCheckBox.isSelected());
                queryDto.setPreFilterPath(preFilterPath);

                for (int i = 0; i < dirsListSize; i++) {
                    searchDirPathes.add(dirsListModel.getElementAt(i).toString());
                }
                queryDto.setSearchDirPathes(searchDirPathes);

                for (int i = 0; i < keywordFileListSize; i++) {
                    keywordFiles.add(keywordFileListModel.getElementAt(i).toString());
                }
                queryDto.setKeywordFiles(keywordFiles);
                isStop = false;
                setHasPrepared(false);
                setIsQuerying(true);
            }
        }

        @Override
        protected String doInBackground() {
            // Your Task's code here.  This method runs
            // on a background thread, so don't reference
            // the Swing GUI from here.
            String textResult = "";
            if (!isStop) {
                long startTime = System.currentTimeMillis();
                setMessage(resourceMap.getString("status.querying.alert"));
                SearchUrl searchUrl = new SearchUrl();

                List<SearchResult> results = searchUrl.searchUrl(queryDto);

                textResult = TextFileTools.buildTextResultByUrl(results);
                long endTime = System.currentTimeMillis();
                setMessage(resourceMap.getString("status.query.time.cost.pre") + (endTime - startTime) / 1000 + resourceMap.getString("status.query.time.cost.post"));
            }
            return textResult;  // return your result
        }

        @Override
        protected void succeeded(String result) {
            // Runs on the EDT.  Update the GUI based on
            // the result computed by doInBackground().
            if (result != null && !result.equals("")) {
                saveResultFileChooser.setSelectedFile(new File(SearchUrlContants.DEFAULT_FILE_NAME + "(" + DateTools.getStringFromDate(new java.util.Date()) + ").txt"));
                int option = saveResultFileChooser.showSaveDialog(mainPanel);
                if (option == JFileChooser.APPROVE_OPTION) {
                    File file = saveResultFileChooser.getSelectedFile();
                    if (!file.getName().endsWith(".txt")) {
                        file = new File(file.getParentFile(), file.getName() + ".txt");
                    }
                    //TODO if there is a same file...
                    TextFileTools.writeTextToFile(result, file);
                }
            } else {
                 JOptionPane.showMessageDialog(mainPanel, resourceMap.getString("info.queryblank.content"), resourceMap.getString("warning.title"), JOptionPane.INFORMATION_MESSAGE);
            }
            setHasPrepared(true);
            setIsQuerying(false);
        }
    }

    @Action(enabledProperty = "isQuerying")
    public void stopQuery() {
        setHasPrepared(true);
        isStop = true;
        setIsQuerying(false);
        if ((queryTask != null) && !queryTask.isDone()) {
            queryTask.cancel(true);
        }
    }
    // Variables declaration - do not modify//GEN-BEGIN:variables
    private javax.swing.JButton addButton;
    private javax.swing.JButton addDirButton;
    private javax.swing.JLabel appTitleLabel;
    private javax.swing.JPanel destDirPanel;
    private javax.swing.JList dirsList;
    private javax.swing.JScrollPane jScrollPane1;
    private javax.swing.JScrollPane jScrollPane2;
    private javax.swing.JFileChooser keywordFileFileChooser;
    private javax.swing.JList keywordFilesList;
    private javax.swing.JPanel keywordsFilesPanel;
    private javax.swing.JButton loadDirsButton;
    private javax.swing.JButton loadListButton;
    private javax.swing.JFileChooser loadListFileChooser;
    private javax.swing.JPanel mainPanel;
    private javax.swing.JMenuBar menuBar;
    private javax.swing.JButton preFilterButton;
    private javax.swing.JCheckBox preFilterCheckBox;
    private javax.swing.JPanel preFilterPanel;
    private javax.swing.JTextField preFilterTextField;
    private javax.swing.JFileChooser prefilterFileChooser;
    private javax.swing.JProgressBar progressBar;
    private javax.swing.JButton queryButton;
    private javax.swing.JButton removeButton;
    private javax.swing.JButton removeDirButton;
    private javax.swing.JButton resetButton;
    private javax.swing.JCheckBox restrict211CheckBox;
    private javax.swing.JButton saveDirsButton;
    private javax.swing.JButton saveListButton;
    private javax.swing.JFileChooser saveListFileChooser;
    private javax.swing.JFileChooser saveResultFileChooser;
    private javax.swing.JFileChooser searchDirFileChooser;
    private javax.swing.JLabel statusAnimationLabel;
    private javax.swing.JLabel statusMessageLabel;
    private javax.swing.JPanel statusPanel;
    private javax.swing.JButton stopButton;
    // End of variables declaration//GEN-END:variables
    private final Timer messageTimer;
    private final Timer busyIconTimer;
    private final Icon idleIcon;
    private final Icon[] busyIcons = new Icon[15];
    private int busyIconIndex = 0;
    private DefaultListModel keywordFileListModel = new DefaultListModel();
    private DefaultListModel dirsListModel = new DefaultListModel();
    private JDialog aboutBox;
    private boolean isStop;
    private StartQueryTask queryTask = null;
}
